package main

import (
	"ehsm_kms/cmd/server/wire"
	"ehsm_kms/pkg/cfgstruct"
	"ehsm_kms/pkg/couchdb"
	"ehsm_kms/pkg/log"
	"ehsm_kms/pkg/process"
	"ehsm_kms/pkg/server/http"
	"encoding/json"
	"fmt"
	"github.com/spf13/cobra"
	"os"
	"path/filepath"
)

type Config struct {
	RunMode string `help:"运行模式[cluster|single]" default:"cluster"`
	ApiKey  string `help:"apikey" default:"guanyishujukejis"`
	Server  http.Config
	DB      couchdb.Config
	Log     log.Config
}

var (
	configFile string
	rootCmd    = &cobra.Command{
		Use:   "ehsm_kms",
		Short: "KMS服务",
	}
	runCmd = &cobra.Command{
		Use:   "run",
		Short: "运行",
		RunE:  cmdRun,
	}
	setupCmd = &cobra.Command{
		Use:         "setup",
		Short:       "初始化配置文件",
		RunE:        cmdSetup,
		Annotations: map[string]string{"type": "setup"},
	}
	configCmd = &cobra.Command{
		Use:   "config",
		Short: "查看当前所有配置",
		RunE:  cmdConfig,
	}
	runConfig   Config
	setupConfig Config
)

func main() {
	currentDir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
	defaultConfig := filepath.Join(currentDir, process.DefaultCfgFilename)
	cfgstruct.SetupFlag(rootCmd, &configFile, "config", defaultConfig, "配置文件")
	//根据环境读取默认配置
	defaults := cfgstruct.DefaultsFlag(rootCmd)
	//程序目录
	rootDir := cfgstruct.ConfigVar("ROOT", currentDir)
	//设置系统的HOME变量
	envHome := cfgstruct.ConfigVar("HOME", os.Getenv("HOME"))
	rootCmd.AddCommand(runCmd)
	rootCmd.AddCommand(setupCmd)
	rootCmd.AddCommand(configCmd)
	process.Bind(runCmd, &runConfig, defaults, cfgstruct.ConfigFile(configFile), envHome, rootDir)
	process.Bind(configCmd, &runConfig, defaults, cfgstruct.ConfigFile(configFile), envHome, rootDir)
	process.Bind(setupCmd, &setupConfig, defaults, cfgstruct.ConfigFile(configFile), envHome, cfgstruct.SetupMode(), rootDir)
	process.Exec(rootCmd)
}

func cmdRun(cmd *cobra.Command, args []string) error {
	ctx, cancel := process.Ctx(cmd)
	defer cancel()
	logger := log.NewLog(&runConfig.Log)
	app, cleanup, err := wire.NewWire(logger, &runConfig.Server, &runConfig.DB)
	defer cleanup()
	if err != nil {
		panic(err)
	}
	if err = app.Run(ctx); err != nil {
		panic(err)
	}
	return nil
}

func cmdSetup(cmd *cobra.Command, args []string) error {
	return process.SaveConfig(cmd, configFile)
}

func cmdConfig(cmd *cobra.Command, args []string) error {
	fmt.Printf("当前运行环境：[%s]\n", cfgstruct.DefaultsType())
	fmt.Println("当前配置文件路径：", configFile)
	output, _ := json.MarshalIndent(runConfig, "", " ")
	fmt.Println(string(output))
	return nil
}
